grammar Pie;

program: ( functionDefinition | statement)+ EOF; // [程序节点]  √

structDefinition: // [结构体定义]  √
	'struct' name = ID '{' vardef (',' vardef)* '}' NL;

functionDefinition: // [函数定义]  √
	'def' ID '(' (vardef (',' vardef)*)? ')' slist;

slist: ':' NL statement+ '.' NL | statement; // [代码块]  √

statement:
	structDefinition							# structStatement
	| qid '=' expr NL							# assignStatement // [赋值语句]  √
	| 'return' expr NL							# returnStatement // [返回语句]
	| 'print' expr NL							# printStatement // [打印语句]  √
	| 'if' expr c = slist ('else' el = slist)?	# ifStatement // [If语句]  √
	| 'while' expr slist						# whileStatement // [While语句]  √
	| call NL									# callStatement // Visit(call)
	| NL										# emptyStatement;

call: name = ID '(' (expr (',' expr)*)? ')'; // [函数调用语句]

expr:
	expr '*' expr		# mulExpr // [乘法表达式]  √
	| expr '+' expr		# addExpr // [加法表达式]  √
	| expr '-' expr		# subExpr // [减法表达式]  √
	| expr '==' expr	# equalExpr // [判等表达式]  √
	| expr '<' expr		# lessThanExpr // [小于表达式]  √
	| atom				# atomExpr;

atom:
	INT // [整数型字面量]  √
	| CHAR // [字符型字面量]  √
	| FLOAT // [浮点型字面量]  √
	| STRING // [字符串字面量]  √
	| qid
	| call
	| instance
	| '(' expr ')';

instance: 'new' sname = ID; // [New表达式]  √

qid:
	qid '.' qid	# memberAccess // [成员访问]  √
	| ID		# varReference; // [符号引用]  √

vardef: ID; // [变量定义]  √

// L e x i c a l  R u l e s

NL: '\r'? '\n';

ID: LETTER (LETTER | '0' ..'9')*;

fragment LETTER: ('a' ..'z' | 'A' ..'Z');

CHAR: '\'' . '\'';

STRING: '"' .*? '"';

INT: '0' ..'9'+;

FLOAT: INT '.' INT* | '.' INT+;

WS: (' ' | '\t') -> channel(HIDDEN);

SL_COMMENT: '#' ~('\r' | '\n')* -> channel(HIDDEN);